Hermes Kanban 多智能体协作方案详解
基于 hermes-kanban-v1-spec.pdf, Nous Research,2026年4月25日
状态:DESIGN ONLY,尚未实现
一、Motivation:为什么需要 Kanban
Hermes 现有唯一的多 Agent 协作原语是 delegate_task(同步 fork-join 子 Agent 调用),适合短小的自包含推理子任务。但以下四类场景它无法覆盖:
| 场景 | 举例 | delegate_task 为什么不够 |
|---|---|---|
| 研究分诊与综合 | 并行专家输出结论 → 评审选优,人工中途纠正 | 途中需要人工介入、结果需持久化 |
| 定时循环任务 | 每日简报、每周报告、每小时邮件分拣 | 需要跨天持久化、中途失败需可恢复 |
| 数字孪生/持久助手 | 有名字的长期角色,累积记忆和偏好 | 根本没有父 Agent,是独立长期存在的 Agent |
| 端到端工程管线 | 分解 → 并行实现 → 审查 → 迭代 → PR | 时长数小时、多人介入、跨 profile 协作 |
二、竞品教训
2.1 三个系统对比
| 系统 | 形态 | 任务粒度 | Agent 身份 | 持久化 | 失败模式 |
|---|---|---|---|---|---|
| Cline Kanban | 本地 board | 一卡 = 一 worktree | 每卡匿名 | DB + git | 崩溃 worker = 残留 worktree |
| Paperclip | 服务器 + UI + 公司模型 | Goal → 项目 → Issue | 持久"员工"身份 | 中心 DB | 崩溃 Agent = 孤立任务(可恢复) |
| NanoClaw Agent Swarms | 进程内 SDK 子 Agent | 从 team-lead 派生 | 每次派生匿名 | 短暂,绑定 query() | 子 Agent 被静默终止,零产出 |
2.2 核心教训
NanoClaw 是反面教材:在 Claude Agent SDK 非交互式 query() 模式下,子 Agent 在 team-lead 完成回合时会被静默终止——看起来成功,实际零产出。
根本原因:协调依赖于上游 SDK 的内部生命周期,SDK 无法保证子 Agent 存活。
Hermes Kanban 的设计原则:
- 采用 Cline 的 board + links + 临时工作区形态
- 借用 Paperclip 的原子认领 + 持久 Agent 身份(映射到已有 Hermes profiles)
- 拒绝 NanoClaw 的进程内子 Agent 蜂群——每个 worker 都是完整 OS 进程
- 继承 Google Gemini 的可移植 profile 产物 + @mention 委托语法
- 拒绝 企业级治理内核——治理 = 用户空间 profiles + plugins
三、三层架构
┌─────────────────────────────────────────────┐
│ CONTROL PLANE(控制层) │
│ 用户:CLI / Telegram / Discord │
└──────────────────┬──────────────────────────┘
│
↓
┌─────────────────────────────────────────────┐
│ STATE PLANE(状态层) │
│ kanban.db(SQLite,WAL 模式) │
│ ┌──────────────────────────────────────┐ │
│ │ DISPATCHER(cron,60s 触发) │ │
│ │ 1. 重算 READY(父任务全部 done?) │ │
│ │ 2. 原子认领(CAS) │ │
│ │ 3. 派发 worker │ │
│ └──────────────────────────────────────┘ │
└──────────────────┬──────────────────────────┘
│
↓
┌─────────────────────────────────────────────┐
│ EXECUTION PLANE(执行层) │
│ planner researcher inbox-triage │
│ workspace workspace workspace │
│ (scratch) (scratch) (dir:~/Mail) │
└─────────────────────────────────────────────┘
三层职责:
- 控制层:用户通过
/kanban命令或hermes kanbanCLI 与 board 交互 - 状态层:SQLite 是唯一真实数据源;dispatcher 定时扫描 + 原子认领 + 派发
- 执行层:每个 worker 是完整 Hermes 进程(
hermes -p <profile> chat -q ...),有自己的 HERMES_HOME、记忆、技能、工作区
关键不变式:永远不允许进程内子 Agent 蜂群。每个 worker 都是独立 OS 进程,通过 board 协调,不直接通信。
四、数据模型
4.1 SQLite Schema
CREATE TABLE tasks (
id TEXT PRIMARY KEY, -- 如 "t_9f2a"
title TEXT NOT NULL,
body TEXT, -- 可选的开场帖子
assignee TEXT, -- profile 名,null=未分配
status TEXT NOT NULL, -- todo|ready|running|blocked|done|archived
priority INTEGER DEFAULT 0,
created_by TEXT, -- profile 名或 "user"
created_at INTEGER NOT NULL,
started_at INTEGER,
completed_at INTEGER,
workspace_kind TEXT NOT NULL DEFAULT 'scratch', -- scratch|worktree|dir
workspace_path TEXT, -- 认领时解析
claim_lock TEXT, -- host+pid,NULL=空闲
claim_expires INTEGER, -- unix ts,过期认领恢复
tenant TEXT -- 可选,多租户命名空间
);
CREATE TABLE task_links (
parent_id TEXT NOT NULL,
child_id TEXT NOT NULL,
PRIMARY KEY (parent_id, child_id)
);
CREATE TABLE task_comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id TEXT NOT NULL,
author TEXT NOT NULL, -- profile 名或 "user"
body TEXT NOT NULL,
created_at INTEGER NOT NULL
);
CREATE TABLE task_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
task_id TEXT NOT NULL,
kind TEXT NOT NULL, -- status_change|claim|release|error
payload TEXT, -- JSON,诊断用
created_at INTEGER NOT NULL
);
CREATE INDEX idx_tasks_assignee_status ON tasks(assignee, status);
CREATE INDEX idx_links_child ON task_links(child_id);
CREATE INDEX idx_comments_task ON task_comments(task_id, created_at);
4.2 状态机
todo ──所有父done──→ ready ──原子认领──→ running ──完成──→ done
│ ↑ │
│ │ block
│ │ ↓
└───────────────── Human/Peer unblock ── blocked
│
archive
↓
archived
| 状态 | 所有者 | 含义 |
|---|---|---|
todo |
创建者 | 存在未完成的父任务 |
ready |
dispatcher | 所有父任务 done,具备认领资格 |
running |
worker | 已被认领,正在执行 |
blocked |
worker | 需要人工或同伴输入才能继续 |
done |
worker | 完成,触发子任务重新评估 |
archived |
用户 | 从默认视图移除,工作区可 GC |
4.3 Workspace 三种类型
| 类型 | 认领时解析 | 适用场景 |
|---|---|---|
scratch |
~/.hermes/kanban/workspaces/<id>/ 新建临时目录 |
研究任务、一次性分析等临时性工作 |
worktree |
git worktree add .worktrees/<id>/ |
编码任务,隔离 git commit |
dir:<path> |
已有目录路径直接挂载进 worker | 长期 journal(Obsidian vault、邮件目录) |
默认是
scratch,因为大多数非编码工作不需要 git。
五、八种协作模式
这些模式全部从基础原语(task + links + comments + assignee + workspace)推导出来,无需扩展 schema。
P1 — Fan-out(扇出)
形态:一个 profile、N 个并列任务、无依赖。
hermes kanban create "angle: cost" --assignee researcher
hermes kanban create "angle: latency" --assignee researcher
hermes kanban create "angle: tool-quality" --assignee researcher
hermes kanban create "angle: licensing" --assignee researcher
# → 4个任务全部 ready,并行派发到 4 个 researcher 进程
P2 — Pipeline(流水线)
形态:不同 profile 按序接力,每阶段产出是下一阶段的输入。
T1 (planner) → T2 (scout) → T3 (editor) → T4 (writer)
↑父结果 ↑父结果
feed 进 body feed 进 body
P3 — Voting/Quorum(投票/仲裁)
形态:N 个 worker 竞速或独立产出,聚合器从中选优。
T1 (analyst) ← T2(T3(T4(T5 # 4个并行调研
↓
T6 (aggregator) # 看到所有父结果,做出裁决
P4 — Long-running journal(长期日志)
形态:同一 profile + 同一 dir workspace + 定时循环任务。
# 每日简报追加到 Obsidian vault
hermes kanban create "daily brief" \
--assignee analyst \
--workspace dir:~/Obsidian/AI-Funding/ \
--schedule "0 9 * * 1-5"
profile 的持久记忆 + 共享目录 → 工作跨次累积,board 作为审计时间线。
P5 — Human-in-the-loop triage(人工介入分诊)
形态:Block → 提问 → Unblock。
# researcher 遇到 gated source,卡住
(hermes) hermes kanban block T3 "source gated; alternative?"
# 用户回复
/kanban comment T3 "use arxiv-sanity mirror"
/kanban unblock T3
# dispatcher 重新派发 worker,worker 读完整评论线程
P6 — @mention delegation(@提及委托)
形态:消息中 @<profile-name> 即隐式创建任务,灵感来自 Google Gemini CLI。
用户:"@researcher 帮我调研一下 Gemini 2 的市场表现"
→ 系统解释为:hermes kanban create "调研 Gemini 2 市场表现" --assignee researcher
无需离开聊天界面,board 提供持久化保证。
P7 — Thread-scoped workspace(线程级工作区)
形态:在有线程的消息平台(Telegram群组等),/kanban here 派生任务,其 workspace 绑定到线程关联的本地目录。
多 profile 在同一线程操作时共享工作目录,不打架。
P8 — Fleet farming(舰队扩展)
形态:一个专精 profile + N 并行任务 + 每任务独立 dir。
# 50个 Instagram 账号的社交媒体运营
for i in $(seq 1 50); do
mkdir -p ~/insta/acct-$i/{assets,drafts,logs}
hermes kanban create "engage acct-$i" \
--assignee insta-manager \
--workspace dir:~/insta/acct-$i/ \
--tenant acct-$i
done
# → 50个任务同时 ready,50个 insta-manager 进程并行认领
每个账号独立 workspace、独立 tenant 命名空间日志。
六、Orchestrator Profile 模式
6.1 问题
用户反馈(sudo_relax,Nous Discord,2026.04.26):
"即使创建了 Researcher、Writer、QA 等独立 profile,orchestrator 还是经常自己把活干了。Orchestrator 应该是控制室,不是工作者。"
6.2 三个属性
1. 禁用执行 toolsets
# orchestrator profile
toolsets:
- kanban # 只能操作 board
- gateway # 只能发消息
- memory # 只能读写记忆
# 明确禁用:
disabled_toolsets:
- terminal
- file
- web
- browser
- code
它根本没法自己干活,被迫委托。
2. 规范化 orchestrator skill
系统消息简短且规定性:
- "你是调度员,不是工作者"
- "任何具体任务 → 创建 kanban 任务并分配给专家 profile,不尝试执行"
- "如果没有任何专家适合,问用户该创建什么 profile,不要默认自己来干"
3. 标准专精 roster 约定
| Profile | 一句话描述 |
|---|---|
researcher |
信息检索、竞品分析、技术调研 |
writer |
文案撰写、内容编排、文档编辑 |
analyst |
数据分析、图表生成、洞察提炼 |
backend-eng |
后端实现、API 设计、数据库 |
frontend-eng |
前端实现、UI 搭建、样式调试 |
reviewer |
代码审查、质量把关、风险识别 |
ops |
部署、监控、日志分析 |
6.3 可安装 profile 模板
hermes profile install orchestrator # 调度员
hermes profile install researcher # 专家们
hermes profile install writer
hermes profile install analyst
hermes profile install reviewer
hermes profile install ops
# → 舰队上线,随时待命
这是 Paperclip"公司模板"思路的轻量化实现,同时关闭了 Gemini subagent-as-file 的功能差距。
七、多租户支持
7.1 最小化 schema 变更
ALTER TABLE tasks ADD COLUMN tenant TEXT; -- 可选,默认为 NULL
CREATE INDEX idx_tasks_tenant ON tasks(tenant);
一个可选列,所有隔离逻辑从中导出。
7.2 四轴隔离
| 维度 | 实现方式 |
|---|---|
| Workspace | workspace_path 位于 tenant 目录下:~/tenants/<tenant>/ |
| Memory | HERMES_TENANT 环境变量,profile 记忆按前缀 namespace 隔离 |
| Board 视图 | hermes kanban list --tenant <tenant> 过滤;per-tenant /kanban 通过 P7 固定到线程 |
| 审计 | 所有 task_events 行都带 tenant 标签,一行 SQL 导出完整历史 |
7.3 共享的部分
- Profile 身份:一个
researcherprofile 存在,被不同 tenant 复用 - Dispatcher:一个 cron job、一个 board、所有 tenant 共用
- Orchestrator:同一 orchestrator 实例给所有 tenant 分配任务,自动向下传播 tenant 到子任务
7.4 "小公司服务多客户"问题
researcher profile (同一个)
│
├── --tenant business-a → ~/tenants/business-a/data/
└── --tenant business-b → ~/tenants/business-b/data/
一个 researcher,两个业务上下文。边界由文件系统路径和内存前缀 enforcement 保证,无需新增实体类型。
八、Kanban vs. delegate_task(边界划分)
这是整个设计的核心问题。
| 维度 | delegate_task |
Kanban |
|---|---|---|
| 形态 | RPC 调用(fork → join) | 持久化消息队列 + 状态机 |
| 父生命周期 | 阻塞直到子返回 | 父在创建后即可退出 |
| 子生命周期 | 短暂;返回后死亡 | 每次运行短暂;任务跨运行持久 |
| 上下文传递 | 调用时传 goal + context 字符串 | 任务标题 + body + 评论线程 + 父结果(从 board 读取) |
| 身份 | 匿名子 Agent,无持久自我 | 命名 profile;自己的 HERMES_HOME、记忆、技能、历史 |
| 可恢复性 | 无;失败 = 失败,父从头重试 | blocked → unblock → 重跑;崩溃 → 15分钟后自动回收 |
| 人工介入 | 无;无头运行 | 任何时刻可评论、block、unblock、重新分配 |
| 依赖图 | 父 Agent 头脑中手动维护 | 一级 task_links;dispatcher 强制执行顺序 |
| 审计轨迹 | 在父上下文压缩时丢失 | SQLite 行永久持久化 |
| 协调形态 | 严格层级(调用者 → 被调用者) | 同级;任何 profile 或人都能读/写任何任务 |
| Agent 间通信 | 无 | Board 介导,持久化,异步 |
一句话区分:delegate_task 是函数调用;Kanban 是一个持久化工作队列,每一次交接都是一行数据库记录,任何 profile(或人)都能看到和编辑。
决策树:
- 用
delegate_task:父需要子结果才能继续;子任务是自包含短推理;秒到分钟级;无人介入;结果回到父上下文 - 用 Kanban:跨 Agent 边界交接;需跨重启持久化;可能需要人工输入;可能由不同角色接力;完成后需可发现
两者共存:Kanban worker 内部仍可调用 delegate_task 做内部推理,这是正常预期。
九、Dispatcher 设计
9.1 刻意设计的"哑巴"dispatcher
Dispatcher 只有三个操作:
- 重算 ready:对每个
todo任务,若所有父链接都到达done,转为ready - 原子认领:对每个
ready+claim_lock IS NULL+assignee IS NOT NULL的任务,执行 CAS - 派发 worker:解析 workspace,执行
hermes -p <assignee> -w <workspace> chat -q "work kanban task <id>" - 过期回收:对
running+claim_expires < now的任务,重置为ready
9.2 并发正确性
BEGIN IMMEDIATE;
UPDATE tasks
SET status = 'running',
claim_lock = :host_pid,
claim_expires = :now + 900,
started_at = :now
WHERE id = :id
AND status = 'ready'
AND claim_lock IS NULL; -- CAS 条件
-- changes() == 1 → 赢;== 0 → 输,继续
COMMIT;
SQLite WAL 模式 + BEGIN IMMEDIATE 事务 + 行级 CAS,最多只有一个认领者能赢。
9.3 智能路由不在内核
"智能路由"、"自动分配"、"优先级队列" 全部是用户空间 concerns,可以通过一个 router profile 实现,无需改动 dispatcher:
# router profile 的工作:扫描 unassigned tasks,重新分配
hermes kanban list --status ready --assignee null
hermes kanban assign <id> <best-profile>
十、CLI 命令表面
hermes kanban init # 创建数据库
hermes kanban create "<title>" # 创建任务
[--body ...] # 附言
[--assignee P] # 分配给某 profile
[--workspace K] # scratch|worktree|dir:<path>
[--tenant T] # 多租户命名空间
[--parent <id>] # 设置父任务(自动建立链接)
hermes kanban list [--mine] [--assignee P] [--status S] [--tenant T] [--json]
hermes kanban show <id> # 详情+评论+事件
hermes kanban assign <id> <profile> # 分配/重分配
hermes kanban link <parent> <child> # 添加依赖
hermes kanban unlink <parent> <child> # 移除依赖
hermes kanban claim <id> # 手动原子认领
hermes kanban comment <id> "<text>" # 追加评论
hermes kanban complete <id> [--result "..."] # 标记完成
hermes kanban block <id> "<reason>" # 阻塞
hermes kanban unblock <id> # 解阻塞
hermes kanban archive <id> # 归档
hermes kanban dispatch # 手动触发一次 dispatcher 扫描
十一、实现计划(8个独立 PR)
| PR | 内容 | 依赖 |
|---|---|---|
| 1 | 脚手架:kanban.py、kanban_db.py、DESIGN.md、skill 骨架 |
无 |
| 2 | 单 profile 路径:create/list/show/claim/complete/comment | PR1 |
| 3 | 依赖解析:link/unlink,done 时自动重算 ready | PR2 |
| 4 | 原子认领 + workspace:CAS 认领、ensure_workspace()、过期回收 |
PR2 |
| 5 | Dispatcher:一次性扫描 + cron 模板 | PR4 |
| 6 | Gateway 集成:/kanban slash 命令,running-agent 守卫逻辑 |
PR2 |
| 7 | Worker skill:教 profile 如何处理 spawn | PR5 |
| 8 | 可移植 profile 产物:hermes profile export/install |
PR1 |
零改动范围:run_agent.py、model_tools.py、toolsets.py、agent/ 目录——全部不受影响。
十二、刻意不做的功能
| 功能 | 属于 |
|---|---|
| 智能路由/自动分配 | 用户空间 router profile |
| 组织架构/层级 | Profile 命名约定 + skills,非 schema 变更 |
| 每 Agent 预算 | plugin,非任务字段 |
| 舰队管理仪表板 | dashboard plugin |
| 审批门 | 复用 tools/approval.py,非新状态 |
| 治理控制平面 | router profile + budget plugin + audit-export plugin 组合,非内核 |
十三、风险管理
| 风险 | 缓解方案 |
|---|---|
| SQLite 跨进程争用 | WAL 模式 + BEGIN IMMEDIATE + 短持锁,已在 hermes_state.py 验证 |
| 残留 workspace 堆积 | hermes kanban gc 定期清理,archive 时触发 |
| Cron 在笔记本睡眠/唤醒时漂移 | 每次 CLI 调用执行一次轻量"mini dispatch",任务最多延迟几分钟 |
| 失控自动化链(A 完成 → 自动触发 B → 无人工介入) | 可选 --require-approval flag,分配给审批 profile 才能继续 |
十四、总结
Hermes Kanban 的本质是一个最小化协作内核:
- 1 个 SQLite 文件
- 1 个 CLI 子命令
- 1 个 skill
- 1 个 cron job
- 零内核改动
所有复杂功能(编排、多租户、审批、仪表板)都在用户空间 profiles 和 plugins 里实现——即使这些功能崩溃,也不会动摇协作结构本身。
和 delegate_task 的关系:共存、不互斥。判断标准只有一条:
这次交接是否需要跨单次 API 循环存活并对他人可见?
是 → Kanban;否 →delegate_task
参考:hermes-kanban-v1-spec.pdf,Nous Research,2026年4月25日,Revision 01